#pragma once

/* 持久目标是指可以动态扩张的对象内存池, 这种持久目标一般不需要考虑回收(一般复用即可)。 通过将持久目标集中在同一个池里可以改善 tlbmiss */
#include <compl.h>
#include <dinfra/list.h>
/* 持久目标 */
typedef struct pheap{
	void		*fptr;
	void		*eptr;
}pheap_t;

SAI void pheap_init(pheap_t *ph, void *ptr, size_t size){
	ph->fptr = ptr;
	ph->eptr = ptr + size;
}

SAI void *pheap_palloc(pheap_t *ph, size_t size){
	void *eptr = ph->eptr;
	if (((size_t)ph->fptr + size) > (size_t)eptr) return NULL;
	void *ret = faa(&ph->fptr, size);
	if ((size_t)ret + size > (size_t)eptr) return NULL;
	return ret;
}

#define __DEF_POBJ_PHEAP_THP(objname, totalsize, hugepagesize) \
static byte_t pheap_pool_##objname[totalsize] ALIGN(hugepagesize);\
static pheap_t pheap_##objname = { .fptr = pheap_pool_##objname, .eptr = ((char *)pheap_pool_##objname) + totalsize };\
SAI void *pheap_palloc_##objname (size_t size){ void *ret = pheap_palloc(&pheap_##objname, size); if (!ret) fatal("pheap " #objname "run over\n"); return ret;}\
SAI void pheap_pfree_##objname (void *ptr, size_t size){ PARAM_USED(ptr, size); fatal("pheap can not free\n");}


/* 线程数是有限的, 因此可以最大规划 */
#define DEF_POBJ_PHEAP(objname, totalsize)	__DEF_POBJ_PHEAP_THP(objname, totalsize, PAGE_SIZE)

#define DEF_POBJ_PHEAP_HUGEPAGE(objname, totalsize, hugepagesize, mkhugepage) \
__DEF_POBJ_PHEAP_THP(objname, totalsize, hugepagesize)\
SYSINIT_FUNC(objname){ mkhugepage(pheap_pool_##objname, totalsize, 1); INFO("mark hugepage success\n"); }


// #define DEF_POBJ_PDHEAP(objname, totalsize, oalloc) \
// static byte_t pdheap_pool_##objname[totalsize] ALIGN(PAGE_SIZE);\
// static pheap_t pdheap_##objname[2] = { {.fptr = pheap_pool_##objname, .eptr = pheap_pool_##objname + totalsize}, {(void *)0, (void *)0} };\
// static pheap_t *pdheapc_##objname = &pdheap0_##objname[0];\
// SAI void *pdheap_palloc_##objname (size_t size){ \
//	 void *ret = pheap_palloc(pdheaQc_##objname, size); \
//	 if (!ret)/* 内存不够再申请 */{
//		 void *mem = oalloc(totalsize);
//		 ASSUME(mem);
//		 if (cas(&pheap_##objname.fptr,  
//	 }
// }\
// SAI void pdheap_pfree_##objname (void *ptr, size_t size){ }

// /* 带cache的palloc, 如果*/
// SAI void *pcached_palloc(slist_t *flist){
//	 return slist_pop(flist);
// }
// SAI void *pcached_free(slist_t *flist){
//	 return slist_pop(flist);
// }